import { Button, ColumnProps, KdFile, Table, Upload } from '@kedacom/react-next'
import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'
import shallow from 'zustand/shallow'
import {
	BlueLinkSpan,
	BlueSpan,
	GreenSpan,
	StyledBottom,
	Wrap,
	Title,
} from '@/pages/meetingList/MeetingCard/components/docs/style'
import Alert, { confirmModal } from '@/components/Alert'
import { API_MEETING_PREFIX } from '@/utils/constant'
import { IMeetingDocItem, ItemStatus, fetchDeleteMeetingFiles, fetchGetMeetingFiles } from '@/api/meetingSpace'
import { useRequest } from 'ahooks'
import { useCreateContentStore } from '@/pages/create/createContent/store'
import { useDeepCompare } from '@kedacom/hooks'
import { transMeetingDocItem } from '@/pages/meetingList/MeetingCard/components/docs/translator'
import { t } from 'i18next'
import { useGlobalStore } from '@/store/global'
import { updateDescription } from '@/plugins/axios/errorCode'

function isFileExtensionAccept(fileName: string) {
	const ext = ['txt', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'rar', 'zip', 'jpg', 'png', 'bmp']
	for (const x of ext) {
		if (fileName.endsWith(`.${x}`)) {
			return true
		}
	}
	return false
}
export type DocsRef = {
	getFileNumber: () => number
}

const Docs = forwardRef((props, ref: React.Ref<DocsRef>) => {
	useImperativeHandle(ref, () => ({
		getFileNumber() {
			return tableData.length
		},
	}))
	const [preUploadData, setPreUploadData] = useState<IMeetingDocItem[]>([])
	const initUploadFileIds = useRef<string[] | null>(null)
	const [tableData, setTableData] = useState<IMeetingDocItem[]>([])
	const { data, run, runAsync } = useRequest(fetchGetMeetingFiles, {
		manual: true,
		onSuccess: (data) => {
			if (data) {
				if (!initUploadFileIds.current) {
					initUploadFileIds.current = data.map((x) => x.file_id)
				}
				const list = data.map((x) => transMeetingDocItem(x, initUploadFileIds.current))
				setTableData([...list, ...preUploadData])
			}
		},
	})

	const { meetingMoid, preKey } = useCreateContentStore(
		(state) => ({
			meetingMoid: state.meetingMoid,
			preKey: state.preKey,
		}),
		shallow
	)

	const SWITCH = useGlobalStore((state) => state.SWITCH)

	const moid = useMemo(() => (!meetingMoid ? preKey : meetingMoid), [preKey, meetingMoid])

	const Columns: ColumnProps<IMeetingDocItem>[] = [
		{
			dataKey: 'fileName',
			title: t('文件名称'),
			width: 278,
		},
		{
			dataKey: 'creator',
			title: t('上传人员'),
			width: 90,
		},
		{
			dataKey: 'createTime',
			title: t('上传时间'),
			width: 130,
		},
		{
			dataKey: 'fileSize',
			title: t('大小'),
			width: 70,
		},
		{
			dataKey: 'status',
			title: t('状态'),
			width: 90,
			render: (rowData: IMeetingDocItem) => {
				if (rowData.progress === 'checking') {
					return <BlueSpan>{t('正在检查文件...')}</BlueSpan>
				} else if (rowData.progress === 'uploadSuccess') {
					return <GreenSpan>{t('上传成功')}</GreenSpan>
				}
			},
		},
		{
			dataKey: 'action',
			title: t('操作'),
			width: 100,
			render: (rowData: IMeetingDocItem) => {
				if (rowData.progress === 'checking') return ''

				return (
					<>
						<BlueLinkSpan
							onClick={(e) => {
								e.stopPropagation()
								DownloadFile(rowData)
							}}
						>
							{t('下载')}
						</BlueLinkSpan>
						<BlueLinkSpan
							onClick={(e) => {
								e.stopPropagation()
								DeleteFile(rowData)
							}}
						>
							{t('删除')}
						</BlueLinkSpan>
					</>
				)
			},
		},
	]

	useEffect(() => {
		run(moid)
	}, useDeepCompare([data, preUploadData]))

	const DownloadFile = (item: IMeetingDocItem) => {
		if (item.status === '0') {
			Alert(t('文件服务器不存在'))
		} else if (item.status === '2') {
			Alert(t('文件服务器不可访问'))
		} else {
			fetchGetMeetingFiles(moid).then((data) => {
				if (data) {
					let id = data.find((i) => {
						return i.file_id === item.fileId
					})
					if (id) {
						window.open(`${API_MEETING_PREFIX}/meeting_files/${item.fileId}/brower`)
					} else {
						Alert(t('文件不存在'))
						run(moid)
					}
				}
			})
		}
	}

	const DeleteFile = (item: IMeetingDocItem) => {
		if (item.status === '0') {
			Alert(t('文件服务器不存在'))
		} else if (item.status === '2') {
			Alert(t('文件服务器不可访问'))
		} else {
			confirmModal({
				msg: t('是否删除文件{{name}}', { name: item.fileName }),
				onOk: async () => {
					if (!item.fileId) {
						setTableData((data) => {
							return data.filter((value) => {
								return item.fileName !== value.fileName
							})
						})
					} else {
						fetchDeleteMeetingFiles(item.fileId)
							.then((res) => {
								if (res.success) {
									run(moid)
								} else {
									Alert(res.description || t('操作失败！'))
								}
							})
							.catch((err) => {
								Alert(t('删除失败！'))
							})
					}
				},
			})
		}
	}

	const beforeUpload = (file: KdFile) => {
		if (tableData.length === 10) {
			return false
		}
		const fileName = file.name
		if (/ <>'"\\\//.test(fileName)) {
			Alert(t('文件名不可包含特殊字符。'))
			return false
		}
		if (!isFileExtensionAccept(fileName)) {
			Alert(t('文件的格式仅限于：txt、doc、docx、xls、xlsx、ppt、pptx、pdf、rar、zip、jpg、png、bmp。'))
			return false
		}
		if (file.size === 0) {
			Alert(t('上传的文件为空文件，请重新上传！'))
			return false
		} else if (file.size > 20971520) {
			Alert(t('文件过大，请重新选择不超过20MB的文件上传。'))
			return false
		}

		setPreUploadData((pre) => {
			return [
				...pre,
				{
					creator: '',
					fileId: '',
					fileName,
					fileSize: file.size < 0.01 ? `0.01M` : `${(file.size / 1024 / 1024).toFixed(2)}M`,
					fileUrl: '',
					createTime: '',
					status: ItemStatus.notExist,
					progress: 'checking',
				},
			]
		})
		return true
	}

	return (
		<Wrap className="meeting-file-wrap">
			<Title>
				<div className="tip_wrap">
					<div className="file_title">{t('文件列表')}</div>
					<div className="file_number">（{tableData.length}）</div>
				</div>
				<div>
					<Upload
						onSuccess={(response: FetchRes<IMeetingDocItem>, originFile) => {
							if (response) {
								updateDescription(response)
								if (!response.success) {
									const description = response.description ?? ''
									if (description.startsWith(t('被禁止的文件类型'))) {
										Alert(
											t(
												'文件的格式仅限于：txt、doc、docx、xls、xlsx、ppt、pptx、pdf、rar、zip、jpg、png、bmp。'
											)
										)
									} else {
										Alert(description)
									}
								}
							} else {
								Alert(t('上传失败'))
							}
							runAsync(moid).then(() => {
								setPreUploadData((pre) => pre.filter((x) => x.fileName !== originFile.name))
							})
						}}
						onError={(err, r, originFile) => {
							setPreUploadData((pre) => pre.filter((x) => x.fileName !== originFile.name))
							Alert(t('上传失败'))
						}}
						headers={{ 'X-Requested-With': null }}
						action={`${API_MEETING_PREFIX}/meeting_files/${moid}`}
						beforeUpload={(file) => beforeUpload(file)}
						disabled={tableData.length >= 10}
					>
						<Button disabled={tableData.length >= 10}>{t('上传文档')}</Button>
					</Upload>
				</div>
			</Title>
			<Table
				rowIdField={'fileId'}
				data={tableData}
				columns={Columns}
				showOrderColumn={false}
				showSelectColumn={false}
				id="upload-dcs-table"
				className="table_wrap"
				nodata={t('暂无数据')}
				i18n={{ order: t('序号') }}
			/>
			<StyledBottom style={{ padding: '10px' }}>
				<div>{t('会议结束30天后系统自动删除会议文档。')}</div>
				<div>{t('最多上传10个文件，每个文件不超过20MB。')}</div>
				<div>{t('上传的文档格式为：txt、doc、docx、xls、xlsx、ppt、pptx、pdf、rar、zip、jpg、png、bmp。')}</div>
			</StyledBottom>
		</Wrap>
	)
})

export default Docs
